package cc.vv.party.web


import cc.vv.party.beans.model.CheckCode
import cc.vv.party.beans.model.User
import cc.vv.party.beans.vo.OrgVO
import cc.vv.party.beans.vo.UserVO
import cc.vv.party.common.base.BaseController
import cc.vv.party.common.constants.StatusCode
import cc.vv.party.common.constants.SysConsts
import cc.vv.party.common.constants.enums.OrgType
import cc.vv.party.common.constants.enums.TerminalType
import cc.vv.party.common.wrapper.PageWrapper
import cc.vv.party.common.wrapper.ResponseEntityWrapper
import cc.vv.party.exception.BizException
import cc.vv.party.logger.annotation.OperateLog
import cc.vv.party.param.UserEditParam
import cc.vv.party.param.UserListParam
import cc.vv.party.service.CheckCodeService
import cc.vv.party.service.PmcAccountorService
import cc.vv.party.service.PmcPersonService
import cc.vv.party.service.UserService
import com.baomidou.mybatisplus.mapper.EntityWrapper
import commonx.core.content.*
import io.swagger.annotations.Api
import io.swagger.annotations.ApiImplicitParam
import io.swagger.annotations.ApiImplicitParams
import io.swagger.annotations.ApiOperation
import org.hibernate.validator.constraints.Length
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.session.jdbc.JdbcOperationsSessionRepository
import org.springframework.web.bind.annotation.*
import java.util.regex.Pattern
import javax.validation.constraints.NotEmpty

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author Gyb
 * @since 2018-10-12
 */
@RestController
@RequestMapping("/web/user")
@Api(value = "管理员", tags = ["管理员服务端API"], description = "管理员服务端API-服务端管理员相关接口")
class UserController : BaseController() {

    @Autowired
    lateinit var userService: UserService

    @Autowired
    lateinit var repository: JdbcOperationsSessionRepository

    @Autowired
    lateinit var checkCodeService: CheckCodeService

    @Autowired
    lateinit var pmcPersonService: PmcPersonService

    @Autowired
    lateinit var pmcAccountorService: PmcAccountorService

    @OperateLog("登录系统")
    @ApiOperation("登录")
    @ApiImplicitParams(
        value = [
            ApiImplicitParam(value = "账号", name = "account"),
            ApiImplicitParam(value = "密码", name = "password"),
            ApiImplicitParam(value = "验证码编号", name = "codeId"),
            ApiImplicitParam(value = "验证码", name = "checkCode")
        ]
    )
    @PostMapping("/login")
    fun login(
        @RequestParam account: String,
        @NotEmpty(message = "密码不能为空") @RequestParam password: String,
        @RequestParam codeId: String,
        @Length(max = 4, min = 4, message = "验证码必须为4位") @RequestParam checkCode: String
    ): ResponseEntityWrapper<Map<String, Any?>> {
        checkCodeService.selectOne(EntityWrapper<CheckCode>().eq("id", codeId).eq("code", checkCode))
            ?: throw BizException(StatusCode.FIELD_VALUE_ERROR.statusCode, "验证码错误")
        checkCodeService.deleteById(codeId)
        if (account != "admin") {
            val passed = Pattern.matches(SysConsts.REGEX_MOBILE, account)
            if (!passed) {
                throw BizException(StatusCode.FIELD_VALUE_ERROR.statusCode, "账号格式不正确")
            }
        }
        val result = userService.login(account, password)
        val session = getSessionIfAbsent()
        result["token"] = session.id
        session.setAttribute(SysConsts.SESSION_KEY_USER_INFO, result)
        session.setAttribute(SysConsts.SESSION_KEY_USER_ID, result["userId"])
        session.setAttribute(SysConsts.SESSION_KEY_DEVICE, TerminalType.PC)
        session.setAttribute(SysConsts.SESSION_KEY_USER_NAME, result["userName"])
        session.setAttribute(SysConsts.SESSION_KEY_USER_ACCOUNT, result["userAccount"])
        session.setAttribute(SysConsts.SESSION_KEY_USER_ROLE, result["userRole"])
        session.setAttribute(SysConsts.SESSION_KEY_YANAN_ROLE_ID, result["yananRole"])
        val orgList = result["adminOrg"] as List<OrgVO>
//        val orgTree = result["orgTree"] as OrgVO
        session.setAttribute(SysConsts.SESSION_KEY_ADMIN_ORG, orgList)
        session.setAttribute(SysConsts.SESSION_KEY_CURRENT_BRANCH, result["currentBranchInfo"])
        session.setAttribute(SysConsts.SESSION_KEY_MANAGE_ORG_INFO, result["userManageOrg"])
//        session.setAttribute(SysConsts.SESSION_KEY_USER_ORG_TREE, orgTree)

        //获取本地用户存储信息
        val user = userService.selectById(result["userId"].toString())?.transfer<UserVO>()
        session.setAttribute(SysConsts.SESSION_KEY_LOCAL_USER_INFO, user)
        return success(result)
    }

    @ApiOperation("注销")
    @PostMapping("/logout")
    fun logout(): ResponseEntityWrapper<*> {
        val session = getSession()
        session.invalidate()
        repository.deleteById(session.id)
        return success(null)
    }

    @OperateLog(content = "添加用户信息")
    @ApiOperation(value = "添加用户信息", notes = "添加用户信息")
    @PostMapping("/save")
    fun save(@RequestBody param: UserEditParam): ResponseEntityWrapper<Boolean> {
        if ((param.party) == null) {
            throw BizException(StatusCode.MISSING_REQUIRE_FIELD.statusCode, "party字段不能为空")
        }
        if (param.card.isNotNullOrEmpty() && (param.card!!.isIdCard15() || param.card!!.isIdCard18())) {
            throw BizException(StatusCode.MISSING_REQUIRE_FIELD.statusCode, "身份证格式不正确")
        }
        val isAdd = userService.save(param, getCurrentUserId())
        return success(isAdd)
    }

    @OperateLog(content = "修改用户信息")
    @ApiOperation(value = "修改用户信息", notes = "修改用户信息")
    @PostMapping("/update")
    fun update(@RequestBody param: UserEditParam): ResponseEntityWrapper<Boolean> {
        var isUpdate = userService.update(param)
        return success(isUpdate)
    }

    @OperateLog(content = "删除用户信息")
    @ApiOperation(value = "删除用户信息", notes = "单个删除用户信息")
    @ApiImplicitParam(name = "id", value = "用户编号", required = true)
    @GetMapping("/delete/{id}")
    fun deleteUser(@PathVariable id: String): ResponseEntityWrapper<Boolean> {
        val isDelete = userService.deleteById(id)
        return success(isDelete)
    }

    @OperateLog(content = "查看用户信息")
    @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
    @ApiImplicitParam(name = "id", value = "用户编号", required = true)
    @GetMapping("/info/{id}")
    fun info(@PathVariable id: String): ResponseEntityWrapper<UserVO> {
        val vo = userService.info(id)
        return success(vo)
    }

    @OperateLog(content = "查看群众列表")
    @ApiOperation(value = "获取群众列表", notes = "获取群众列表")
    @ApiImplicitParams(
        value = [
            (ApiImplicitParam(name = "size", value = "每页显示数量", required = true)),
            (ApiImplicitParam(name = "page", value = "页码", required = true))
        ]
    )
    @PostMapping(value = "/list/{page}/{size}")
    fun listPage(@RequestBody param: UserListParam, @PathVariable size: Int, @PathVariable page: Int): ResponseEntityWrapper<PageWrapper<UserVO>> {
        val page = userService.listPage(param, size, page)
        return success(page)
    }

    @OperateLog(content = "查看党员列表")
    @ApiOperation(value = "获取党员列表", notes = "获取党员列表")
    @ApiImplicitParams(
        value = [
            (ApiImplicitParam(name = "size", value = "每页显示数量", required = true)),
            (ApiImplicitParam(name = "page", value = "页码", required = true))
        ]
    )
    @PostMapping(value = "/party-member-list/{page}/{size}")
    fun partyMemberListPage(@RequestBody param: UserListParam, @PathVariable size: Int, @PathVariable page: Int): ResponseEntityWrapper<PageWrapper<UserVO>> {
        val page = userService.partyMemberListPage(param, size, page)
        return success(page)
    }

    @OperateLog(content = "查看用户信息")
    @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
    @ApiImplicitParam(name = "id", value = "用户编号", required = true)
    @GetMapping("/party-member-info/{id}")
    fun partyMemberInfo(@PathVariable id: String): ResponseEntityWrapper<UserVO> {
        val vo = userService.partyMemberInfo(id)
        return success(vo)
    }


    @ApiOperation(value = "根据身份证号获取用户信息", notes = "根据身份证号获取用户信息")
    @ApiImplicitParam(name = "idCard", value = "身份证编号", required = true)
    @GetMapping("/info-by-idcard")
    fun partyMemberInfoByIdCard(@RequestParam idCard: String): ResponseEntityWrapper<UserVO> {
        val vo = pmcPersonService.selectPartyMemberByIdCard(idCard.trim()) ?: throw BizException(
            StatusCode.MESSAGE_NOT_EXIST.statusCode,
            "党员信息不存在"
        )
        val localUser: User? = userService.selectById(vo.id)
        if (localUser != null) {
            throw BizException(StatusCode.MESSAGE_EXIST.statusCode, "党员信息已存在")
        }
        return success(vo)
    }

    @ApiOperation(value = "账号检测", notes = "账号检测")
    @ApiImplicitParams(
        value = [
            ApiImplicitParam(name = "account", value = "账号", required = true),
            ApiImplicitParam(name = "orgId", value = "组织机构id,组织机构管理界面中，修改时需要传此参数", required = false)
        ]
    )
    @GetMapping("/check-account")
    fun checkAccount(
        @RequestParam account: String,
        @RequestParam(required = false) orgId: String?
    ): ResponseEntityWrapper<Boolean> {
        pmcAccountorService.checkAccountExists(account, orgId)
        return success(true)
    }

    @ApiOperation(value = "社区大党委、街道联席会议、四支队伍管理员账号检测", notes = "社区大党委、街道联席会议、四支队伍管理员账号检测")
    @ApiImplicitParams(
        value = [
            ApiImplicitParam(name = "account", value = "账号", required = true)
        ]
    )
    @GetMapping("/check-pmc-account")
    fun checkAccount(
        @RequestParam account: String
    ): ResponseEntityWrapper<Boolean> {
        pmcAccountorService.checkPmcAccountExists(account)
        return success(true)
    }

    @ApiOperation(value = "多个账号检测，用\"，\"分割", notes = "多个账号检测")
    @ApiImplicitParam(name = "account", value = "账号", required = true)
    @GetMapping("/check-accounts")
    fun checkAccountList(@RequestParam accounts: List<String>): ResponseEntityWrapper<Boolean> {
        pmcAccountorService.checkAccountListExists(accounts)
        return success(true)
    }

    @ApiOperation(value = "组织机构下的用户数量统计", notes = "组织机构下的用户数量统计")
    @ApiImplicitParams(
        value = [
            ApiImplicitParam(name = "orgId", value = "组织机构编号", required = true),
            ApiImplicitParam(name = "orgType", value = "组织机构类型", required = true)
        ]
    )
    @GetMapping("/user-counts")
    fun userCount(
        @RequestParam orgId: String, @RequestParam orgType: Int
    ): ResponseEntityWrapper<Int> {
        val wrapper = EntityWrapper<User>()
        when (orgType) {
            OrgType.AREA.type -> wrapper.eq("area", orgId).or("area is null")
            OrgType.STREET.type -> wrapper.eq("street", orgId)
            OrgType.SECTION.type -> wrapper.eq("community", orgId)
            OrgType.GRID.type -> wrapper.eq("grid", orgId)
            OrgType.UNIT.type -> wrapper.eq("work_company", orgId)
            else -> throw BizException(StatusCode.FIELD_VALUE_ERROR)
        }
        return success(userService.selectCount(wrapper))
    }

    @ApiOperation(value = "获取单位下的用户", notes = "获取单位下的用户")
    @ApiImplicitParam(name = "unitIds", value = "单位id，多个之间用\",\"分割", required = true)
    @GetMapping("/unit-user-list")
    fun getOrgUserList(@RequestParam unitIds: List<String>): ResponseEntityWrapper<Collection<UserVO>> {
        if (unitIds.isEmpty()) throw BizException(StatusCode.MESSAGE_NOT_EXIST.statusCode, "请先选择单位")
        return success(
            userService.selectList(
                EntityWrapper<User>().`in`("workCompany", unitIds).eq(
                    "party",
                    0
                )
            ).transferEntries<UserVO>()
        )
    }
}
